package com.UnionPayCenter.operation.service.impl;

import com.UnionPayCenter.account.enums.AccountTypeEnum;
import com.UnionPayCenter.coupon.service.CouponQueryService;
import com.UnionPayCenter.mapper.CouponMapper;
import com.UnionPayCenter.mapper.OperationRewardsMapper;
import com.UnionPayCenter.operation.entity.Activity;
import com.UnionPayCenter.operation.entity.ActivityType;
import com.UnionPayCenter.operation.entity.OperationRewards;
import com.UnionPayCenter.operation.entity.dto.ActivityDTO;
import com.UnionPayCenter.operation.entity.dto.ActivityQueryDTO;
import com.UnionPayCenter.operation.entity.dto.OperationRewardsDTO;
import com.UnionPayCenter.operation.entity.vo.ActivityVO;
import com.UnionPayCenter.operation.entity.vo.OperationRewardsVO;
import com.UnionPayCenter.operation.enums.ActivityErrorCodeEnum;
import com.UnionPayCenter.operation.enums.ActivityOperationTypeEnum;
import com.UnionPayCenter.operation.manager.ActivityManager;
import com.UnionPayCenter.operation.manager.ActivityTypeManager;
import com.UnionPayCenter.operation.service.ActivityService;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ActivityServiceImpl implements ActivityService {

    @Autowired
    private ActivityManager activityManager;

    @Autowired
    private ActivityTypeManager activityTypeManager;

    // TODO
    @Autowired
    private OperationRewardsMapper operationRewardsMapper;

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private CouponQueryService couponQueryService;

    @Override
    @Transactional
    public Integer addActivity(ActivityDTO activityDTO) {

        ActivityType activityType = checkAndGetActivityType(activityDTO.getActivityTypeId());

        // 如果是注册, 需要判断店铺是否已经有活动存在
        if (ActivityOperationTypeEnum.REGIST.code() == activityType.getOperationType()) {
            if (isActivityDuplicated(activityType, activityDTO.getShopId())) {
                ActivityErrorCodeEnum.ACTIVITY_EXISTED.exception();
            }
        }

        Activity operationActivity = new Activity();
        BeanUtils.copyProperties(activityDTO, operationActivity);

        // 处理活动类型
        operationActivity.setActivityTypeId(activityType.getActivityTypeId());


        activityManager.addActivity(operationActivity);
        Integer activityId = operationActivity.getActivityId();

        // 处理奖励
        maintainActivityRewards(activityDTO, activityType, activityId);

        return activityId;
    }

    @Override
    @Transactional
    public void deleteActivity(Integer activityId) {
        Activity activity = activityManager.getById(activityId);
        if (activity == null) {
            log.warn("delete not existed activity, activity id {}", activityId);
        }
        operationRewardsMapper.deleteByActivityId(activityId);
        activityManager.deleteById(activityId);
    }

    private boolean isActivityDuplicated(ActivityType activityType, Integer shopId) {
        List<Activity> activities = activityManager.getByShopId(shopId, null);
        if (CollectionUtils.isEmpty(activities)) {
            return false;
        }
        return activities.stream()
                .anyMatch(activity -> activity.getActivityTypeId() == activityType.getActivityTypeId());
    }

    @Override
    @Transactional
    public void updateActivityStatus(ActivityDTO activityDTO) {
        Activity operationActivity = new Activity();
        operationActivity.setActivityId(activityDTO.getActivityId());
        operationActivity.setStatus(activityDTO.getStatus());
        activityManager.updateActivity(operationActivity);
    }

    private ActivityType checkAndGetActivityType(Integer activityTypeId) {
        ActivityType activityType = activityTypeManager.getById(activityTypeId);
        if (activityType == null) {
            ActivityErrorCodeEnum.ACTIVITY_TYPE_NOT_EXIST.exception();
        }
        return activityType;
    }

    private void maintainActivityRewards(ActivityDTO activityDTO, ActivityType activityType, Integer activityId) {
        List<OperationRewardsDTO> operationRewardsDTOS = activityDTO.getOperationRewardsDTOs();
        if (CollectionUtils.isEmpty(operationRewardsDTOS)) {
            return;
        }

        // 处理奖励
        for (OperationRewardsDTO operationRewardsDTO : operationRewardsDTOS) {
            OperationRewards operationRewards = new OperationRewards();
            operationRewards.setActivityId(activityId);
            operationRewards.setQuantity(operationRewardsDTO.getQuantity());
            operationRewards.setCouponsId(operationRewardsDTO.getCouponsId());

            // 只有现金相关才需要账户类型
            if (ActivityOperationTypeEnum.PAY.code() == activityType.getOperationType()
                    || ActivityOperationTypeEnum.BALANCE_PAY.code() == activityType.getOperationType()) {
                operationRewards.setAccountTypeId(AccountTypeEnum.CASH_REWARDS.code());
            }
            operationRewardsMapper.insert(operationRewards);
        }
    }

    @Override
    @Transactional
    public void updateActivity(ActivityDTO activityDTO) {
        Integer activityId = activityDTO.getActivityId();
        Activity dbActivity = activityManager.getById(activityId);
        if (dbActivity == null) {
            log.warn("update not existed activity, activity id {}", activityId);
            return;
        }

        Integer activityTypeId = activityDTO.getActivityTypeId();
        ActivityType activityType = checkAndGetActivityType(activityTypeId);

        // 如果是注册, 需要判断店铺是否已经有活动存在
        //if (activityType.getActivityTypeId().equals(activityTypeId)
        //        && ActivityOperationTypeEnum.REGIST.code() == activityType.getOperationType()) {
        //    if (isActivityDuplicated(activityType, operationActivityDTO.getShopId())) {
        //        ActivityErrorCodeEnum.ACTIVITY_EXISTED.exception();
        //    }
        //}
        // 更新活动
        Activity operationActivity = new Activity();
        BeanUtils.copyProperties(activityDTO, operationActivity);
        activityManager.updateActivity(operationActivity);

        // 更新活动奖品
        List<OperationRewardsDTO> operationRewardsDTOs = activityDTO.getOperationRewardsDTOs();
        if (CollectionUtils.isNotEmpty(operationRewardsDTOs)) {
            operationRewardsMapper.deleteByActivityId(activityDTO.getActivityId());
            maintainActivityRewards(activityDTO, activityType, activityId);
        }
    }

    @Override
    public PageInfo<ActivityVO> getActivity(ActivityQueryDTO activityQueryDTO) {
        PageInfo<Activity> activities = getActivityWithoutRewards(activityQueryDTO);
        Page<ActivityVO> operationActivityVOS = new Page<>();
        BeanUtils.copyProperties(activities, operationActivityVOS);
        for (Activity activity : activities.getList()) {
            ActivityVO operationActivityVO = new ActivityVO();
            BeanUtils.copyProperties(activity, operationActivityVO);
            ActivityType activityType = activityTypeManager.getById(activity.getActivityTypeId());
            if (activityType == null) {
                continue;
            }
            List<OperationRewards> operationRewards = operationRewardsMapper.selectByActivityId(activity.getActivityId());
            if(CollectionUtils.isEmpty(operationRewards)){
                continue;
            }
            if(1 == activity.getRewardsType()){
                //对于优惠券判断是否停用
                operationRewards = operationRewards.stream().filter(e->Objects.nonNull(e.getCouponsId())
                        && couponQueryService.checkCouponValidTag(e.getCouponsId())).collect(Collectors.toList());
            }
            List<OperationRewardsVO> operationRewardsVOS = JSON.parseArray(JSON.toJSONString(operationRewards), OperationRewardsVO.class);
            operationActivityVO.setOperationRewardsDTOs(operationRewardsVOS);
            operationActivityVO.setActivityTypeName(activityType.getTypeName());
            operationActivityVOS.add(operationActivityVO);
        }
        return new PageInfo<>(operationActivityVOS);
    }

    @Override
    public PageInfo<Activity> getActivityWithoutRewards(ActivityQueryDTO activityQueryDTO) {
        Activity operationActivity = new Activity();
        BeanUtils.copyProperties(activityQueryDTO, operationActivity);
        operationActivity.setShopId(activityQueryDTO.getShopId());
        operationActivity.setActivityTypeId(activityQueryDTO.getActivityTypeId());
        Page<Activity> activities = activityManager.getByCondition(operationActivity, activityQueryDTO.getPage(),
                activityQueryDTO.getPageSize());
        return new PageInfo<>(activities);
    }

    @Override
    public List<ActivityVO> getActivityByType(ActivityQueryDTO activityQueryDTO) {
        ActivityType activityType = activityTypeManager.getByType(activityQueryDTO.getOperationType());
        Activity operationActivity = new Activity();
        operationActivity.setShopId(activityQueryDTO.getShopId());
        operationActivity.setActivityTypeId(activityType.getActivityTypeId());
        List<Activity> activities = activityManager.getByCondition(operationActivity, 1, Integer.MAX_VALUE);

        List<ActivityVO> activityVOS = Lists.newArrayListWithCapacity(activities.size());
        for (Activity activity : activities) {
            ActivityVO operationActivityVO = new ActivityVO();
            BeanUtils.copyProperties(activity, operationActivityVO);
            List<OperationRewards> operationRewards = operationRewardsMapper.selectByActivityId(activity.getActivityId());
            List<OperationRewardsVO> operationRewardsVOS = JSON.parseArray(JSON.toJSONString(operationRewards), OperationRewardsVO.class);
            for (OperationRewardsVO operationRewardsVO : operationRewardsVOS) {
                operationRewardsVO.setCouponEntity(couponMapper.selectByPrimaryKey(operationRewardsVO.getCouponsId()));
            }
            operationActivityVO.setOperationRewardsDTOs(operationRewardsVOS);
            activityVOS.add(operationActivityVO);
        }
        return activityVOS;
    }

    @Override
    public ActivityVO getActivityById(Integer activityId) {
        Activity activity = activityManager.getById(activityId);
        if (activity == null) {
            ActivityErrorCodeEnum.ACTIVITY_TYPE_NOT_EXIST.exception();
        }
        ActivityVO operationActivityVO = new ActivityVO();
        BeanUtils.copyProperties(activity, operationActivityVO);
        ActivityType activityType = activityTypeManager.getById(activity.getActivityTypeId());
        if (activityType == null) {
            ActivityErrorCodeEnum.ACTIVITY_TYPE_NOT_EXIST.exception();
        }
        List<OperationRewards> operationRewards = operationRewardsMapper.selectByActivityId(activity.getActivityId());
        List<OperationRewardsVO> operationRewardsVOS = JSON.parseArray(JSON.toJSONString(operationRewards), OperationRewardsVO.class);
        operationActivityVO.setOperationRewardsDTOs(operationRewardsVOS);
        operationActivityVO.setActivityTypeName(activityType.getTypeName());
        return operationActivityVO;
    }
}













